<template>
  <vue-flowchart-editor class="vue-flowchart-editor" ref="flowChart">
    <div class="vfe-chart">
      <!-- Top Menu -->
      <div class="vfe-chart-header" v-if="showRightInfo">
        <editor-toolbar :chart-data="flowChartData" :read-only="readOnly" />
      </div>
      <div class="vfe-chart-container">
        <!-- Left Items -->
        <div class="vfe-chart-sidebar" v-if="!readOnly">
          <editor-item-panel
            :node-items="flowChartNodeItems"
          />
        </div>
        <!-- Main Chart -->
        <div class="vfe-chart-main">
          <flow
            :key="flow_sign"
            ref="flow"
            :autoPaint="true"
            :data="flowChartData"
            :onClick="handleClick"
            :onNodeClick="handleNodeClick"
            :onAfterChange="handleAfterChange"
            :onBeforeChange="handleBeforeChange"
            :onKeyDown="handleKeyDown"
            :graph="graphConfig"
          />
          <!--
            :onNodeDoubleClick="handleNodeDoubleClick"
            :onNodeMouseLeave="handleNodeMouseLeave"
          -->
          <div class="tooltip">
            <template v-for="item in tooltipData">
              <p :key="item.name">{{ item.name }}: {{ item.value }}</p>
            </template>
          </div>
        </div>
        <!-- Right Panel -->
        <div class="vfe-chart-panel" v-if="showRightInfo">
          <div class="vfe-chart-panel-detail">
            <editor-detail-panel :read-only="readOnly" ref="detail_form"/>
          </div>
          <div class="vfe-chart-panel-minimap">
            <editor-minimap />
          </div>
        </div>
      </div>
    </div>
    <!-- Mouse Right Button Context Menu -->
    <editor-context-menu v-if="!readOnly" />
    <register-edge
      name="custom-polyline"
      extend="flow-polyline"
      :config="customEdgeConfig"
    />
    <custom-command :save="saveChartData" :download="downloadImage" ref="custom_command"/>
  </vue-flowchart-editor>
</template>

<script>
import VueFlowchartEditor, { Flow, RegisterEdge } from '../index'
import EditorToolbar from './components/Toolbar'
import EditorItemPanel from './components/ItemPanel'
import EditorDetailPanel from './components/DetailPanel'
import EditorMinimap from './components/EditorMinimap'
import EditorContextMenu from './components/ContextMenu'
import CustomCommand from './components/CustomCommand'
import { throttle } from 'lodash'

export default {
  name: 'FlowchartEditor',

  components: {
    VueFlowchartEditor,
    Flow,
    EditorToolbar,
    EditorItemPanel,
    EditorDetailPanel,
    EditorMinimap,
    EditorContextMenu,
    CustomCommand,
    RegisterEdge,
  },

  props: {
    readOnly: {
      type: Boolean,
      default: false
    },
    chartData: {
      type: Object
    },
    chartDataNodeItems: {
      type: Array
    },
    saveData: {
      type: Function
    },
    showRightInfo: {
      type: Boolean,
      default: false
    }
  },

  data() {
    return {
      flow_sign: (new Date()).getTime(),
      beforeData: null,
      flowChartData: this.chartData,
      flowChartNodeItems: this.chartDataNodeItems,
      graphConfig: {
        mode: 'readOnly',
      },
      customEdgeConfig: {
        getActivedStyle(/*item*/) {
          return {
            lineWidth: 3,
          }
        },
        getSelectedStyle(/*item*/) {
          return {
            lineWidth: 3,
          }
        },
      },
      tooltipDom: null,
      tooltipShow: true,
      tooltipData: [],
    }
  },

  mounted() {
    this.tooltipDom = document.getElementsByClassName('tooltip')[0]
  },

  methods: {
    handleClick(e) {

      if (this.readOnly && !e.item) {
        this.tooltipDom.style.display = 'none'
      }
    },

    handleNodeClick(e) {

    },

    handleNodeMouseLeave: throttle(
      function () {
        // if (this.readOnly) {
        //   console.log(e)
        //   this.tooltipDom.style.display = 'none'
        // }
      },
      1000,
      {
        leading: false,
        trailing: true,
      }
    ),
    handleKeyDown(e){


    },
    handleBeforeChange(e) {

      let data = JSON.stringify(this.$refs.custom_command.getLastData());
      if(data)
        this.beforeData = data;
    },
    handleAfterChange(e) {
      let needReStore = false
      // 查看修改后的数据 看是否删除了开始节点或者开始的连线
      if(
        (e.action == 'remove' && (e.item.model.nodeType == 3 || e.item.model.nodeType == 2))
      ) {
        needReStore = true
      }
      // 开始节点不能再新增连线
      if(e.action == 'add' && e.item.type == 'edge' && (e.item.source.model.nodeType == 2 || e.item.target.model.nodeType == 2)) {
        needReStore = true
      }
      // 如果需要回退
      if(needReStore) {
        // 如果是移除了开始节点 则重置回去
        let curData = JSON.parse(this.beforeData);
        this.$nextTick(() => {
          this.flowChartData = curData
          this.$emit("reload", curData);
        })
      }
    },

    saveChartData(data) {

      data = this.$refs.custom_command.getLastData();

      if(data) {

        // 这里需要做一些校验
        if(data.nodes && data.nodes.length) {

          // 循环节点校验
          for (let node of data.nodes){

            if(node.nodeType != 2) {

              if(!node.nodeCode) {

                this.msgError(`节点 ${node.label} 的节点编码不能为空`);
                return false
              }
              if(!node.remark) {

                this.msgError(`节点 ${node.label} 的节点描述不能为空`);
                return false
              }
              if(node.shows && node.shows.length) {

                node.shows.forEach(show => {

                  if(!show.showStrategy) {

                    this.msgError(`节点 ${node.label} 的显示策略配置不完整`);
                    return false
                  }
                })

              } else {

                this.msgError(`节点 ${node.label} 的显示规则必须配置`);
                return false
              }

              // 校验显示规则部分
              if(node.shows) {

                for(let show of node.shows) {

                  if(show.showStrategy == 1) {

                    if(!show.roleName || !show.roleName.length) {

                      this.msgError(`节点 ${node.label} 必须选择角色参数`);
                      return false
                    }

                    if(!show.agentName || !show.agentName.length) {

                      this.msgError(`节点 ${node.label} 必须选择机构参数`);
                      return false
                    }
                  }
                  if(show.showStrategy == 2 || show.showStrategy == 4) {

                    if(!show.roleName || !show.roleName.length) {

                      this.msgError(`节点 ${node.label} 必须选择角色参数`);
                      return false
                    }
                  }
                  // 如果是固定人员 校验必须选择了人员
                  if(show.showStrategy == 3) {

                    if(!show.userName || !show.userName.length) {

                      this.msgError(`节点 ${node.label} 必须选择人员参数`);
                      return false
                    }
                  }
                }
              }
            }
          }
        }

        if(data.edges && data.edges.length) {

          for(let edge of data.edges) {

            if(!edge.actionName){
              this.msgError(`线的 动作名称没有填写`);
              return false
            }
            if(!edge.actionCode){
              this.msgError(`线的 动作编码没有填写`);
              return false
            }

            if(edge.source && edge.target) {

              edge.sourceCode = data.nodes.find(item => item.id == edge.source).nodeCode;
              edge.targetCode = data.nodes.find(item => item.id == edge.target).nodeCode;
            }
          }
        }
        this.$emit('save-data', data)
      }
    },

    _downloadImage(data, filename = 'flowchart.png') {
      const a = document.createElement('a')
      a.href = data
      a.download = filename
      document.body.appendChild(a)
      a.click()
    },

    downloadImage() {
      const page = this.$refs['flowChart'].propsAPI.editor.getCurrentPage()
      this._downloadImage(page.saveImage().toDataURL('image/png'))
    },
  },

}
</script>

<style lang="less">
.vue-flowchart-editor {
  display: flex;
  flex: 1;
  flex-direction: column;
  width: 100%;
  height: calc(100vh - 200px);
  background: #fff;
}
.vfe-chart {
  position: relative;
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;

  .vfe-chart-header {
    border: 1px solid #e6e9ed;
    padding: 8px;
  }

  .vfe-chart-container {
    flex: 1;
    display: flex;
    justify-content: space-around;
    .vfe-chart-main {
      position: relative;
      flex: 1;
      max-height: ~'calc(100% - 5px)'; // fix scroll show

      .tooltip {
        position: absolute;
        display: none;
        top: 0;
        left: 0;
        width: 100px;
        height: auto;
        padding: 15px;
        border-radius: 10px;
        z-index: 999;
        opacity: 0.8;
        color: #ffffff;
        font-size: 12px;
        background-color: #000;

        p {
          margin: 0;
        }
      }
    }

    .vfe-chart-sidebar {
      position: relative;
      display: flex;
      justify-content: center;
      width: 150px;
      //background-color: #fafafa;
      border-right: 1px solid #e6e9ed;
    }

    .vfe-chart-panel {
      //position: relative;
      width: 320px;
      //background-color: #fafafa;
      border-left: 1px solid #e6e9ed;
      overflow: hidden;
      overflow-y: scroll;
      height:  calc(100vh - 280px);
      .vfe-chart-panel-detail {
        box-sizing: border-box;
        //position: fixed;
        //top: 45px;
        //width: 300px;
        padding: 0px 8px;
        //height: ~'calc(100% - 250px)';
        //overflow-y: auto;
      }

      .vfe-chart-panel-minimap {
        //position: fixed;
        bottom: 0;
        width: 300px;
        height: 200px;
        border-top: 1px solid #e6e9ed;
      }
    }
  }
}
</style>
